package com.lxm.ymcc.service.impl;
import com.google.code.kaptcha.Producer;
import com.lxm.ymcc.constents.RedisConstents;
import com.lxm.ymcc.dto.RegisterPhoneDTO;
import com.lxm.ymcc.dto.RegisterCodeInRedis;
import com.lxm.ymcc.exlipus.GlobalException;
import com.lxm.ymcc.properties.SMSCodeProperties;

import com.lxm.ymcc.result.JSONResult;
import com.lxm.ymcc.service.IMessageSmsService;
import com.lxm.ymcc.service.ISendCodeService;
import com.lxm.ymcc.text.*;
import com.lxm.ymcc.util.AssertUtil;
import com.lxm.ymcc.util.StrUtils;
import com.lxm.ymcc.util.VerifyCodeUtils;
import com.lxm.ymcc.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class SendCodeServiceImpl implements ISendCodeService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private IMessageSmsService messageSmsService;




    @Autowired
    private SMSCodeProperties codeProperties;

    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;


   @Autowired
    private RedisCache redisCache;

    // 保存验证码信息
    String uuid = IdUtils.simpleUUID();
    String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;

    @Override
    public JSONResult imageVerifyCode(String imageCodeKey) {
//        // 调用工具类生成图形验证码
//        String code = StrUtils.getComplexRandomString(4);
//
//        // 将图形码保存到redis中， 并设置五分钟的过期时间
//        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
//
//        // 调用工具类将图形验证码写到图上  并base64编码的字符串
//        String base64Str = VerifyCodeUtils.verifyCode(100, 30, code);
//
//        //返回base64编码的字符串
//        return base64Str;
//    }

       /* String capStr = null, code = null;
        BufferedImage image = null;



        String capText = captchaProducerMath.createText();
        capStr = capText.substring(0, capText.lastIndexOf("@"));
        code = capText.substring(capText.lastIndexOf("@") + 1);
        image = captchaProducerMath.createImage(capStr);


        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        // 调用工具类将图形验证码写到图上  并base64编码的字符串
        String base64Str = VerifyCodeUtils.verifyCode(100, 30, capStr);

        //返回base64编码的字符串
        return base64Str;*/


        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        String captchaType = SMSCodeProperties.getCaptchaType();
        if ("math".equals(captchaType))
        {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            return JSONResult.error(e.getMessage());
        }

        return JSONResult.success(Base64.encode(os.toByteArray()));




    }



    @Override
    public void send(RegisterPhoneDTO dto) {
        //1.图像验证码的验证
        Object redisImageCode = redisCache.getCacheObject(verifyKey);
        AssertUtil.isNotNull(redisImageCode,"图形验证码已经过期");
       AssertUtil.isEqualsIgnoreCase(dto.getImageCode().trim(), redisImageCode.toString().trim(),"图形验证码不正确");

        //2.准备一个验证码
        String code = StrUtils.getRandomString(codeProperties.getLength());
        //存放在redis里面的key
        String key = RedisConstents.REG_IN_REDIS_PREFIX+dto.getMobile();
        //检查redis里面是否已经存放过
        RegisterCodeInRedis codeInRedis = (RegisterCodeInRedis) redisTemplate.opsForValue().get(key);
        if(codeInRedis!=null){
            //1.检查距离上次发送的时间间隔
            if ((System.currentTimeMillis()-codeInRedis.getTime())/1000<codeProperties.getInterval()) {
                throw  new GlobalException("操作频繁，请稍后再试");
            }else {
                code=codeInRedis.getCode();
            }
        }

        //创建一个验证码放到redis里面
        RegisterCodeInRedis newCodeInRedis = new RegisterCodeInRedis(code,System.currentTimeMillis());
        redisTemplate.opsForValue().set(key,newCodeInRedis,5, TimeUnit.MINUTES);

        //4.发送验证码【没做】
        String sms = "您的验证码为："+code+",请在5分钟内使用。";
        System.out.println(sms);

        //5.存储到t_message_sms里面
        messageSmsService.save("用户注册",sms,dto.getMobile());
    }
}
